package com.lineage.server.model.map;

import com.lineage.MapReader;
import com.lineage.TextMapReader;
import com.lineage.server.datatables.MapsTable;
import com.lineage.server.templates.MapData;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class CachedMapReader extends MapReader {
  private static final Log _log = LogFactory.getLog(CachedMapReader.class);
  
  private static final String CACHE_DIR = "./config/mapcache/";
  
  private L1V1Map cacheMap(int mapId) throws IOException {
    File file = new File("./config/mapcache/");
    if (!file.exists())
      file.mkdir(); 
    L1V1Map map = (L1V1Map)(new TextMapReader()).read(mapId);
    DataOutputStream out = new DataOutputStream(
        new BufferedOutputStream(new FileOutputStream("./config/mapcache/" + mapId + ".map")));
    out.writeInt(map.getId());
    out.writeInt(map.getX());
    out.writeInt(map.getY());
    out.writeInt(map.getWidth());
    out.writeInt(map.getHeight());
    byte[][] rawTiles;
    int length = (rawTiles = map.getRawTiles()).length;
    int i = 0;
    while (i < length) {
      byte[] line = rawTiles[i];
      byte[] array;
      int length2 = (array = line).length;
      int j = 0;
      while (j < length2) {
        byte tile = array[j];
        out.writeByte(tile);
        j++;
      } 
      i++;
    } 
    out.flush();
    out.close();
    return map;
  }
  
  public L1Map read(int mapId, MapData mapData) throws IOException {
    File file = new File("./config/mapcache/" + mapId + ".map");
    if (!file.exists())
      return cacheMap(mapId); 
    DataInputStream in = new DataInputStream(
        new BufferedInputStream(new FileInputStream("./config/mapcache/" + mapId + ".map")));
    int id = in.readInt();
    if (mapId != id)
      throw new FileNotFoundException(); 
    int xLoc = in.readInt();
    int yLoc = in.readInt();
    int width = in.readInt();
    int height = in.readInt();
    byte[][] tiles = new byte[width][height];
    byte[][] array;
    int length = (array = tiles).length;
    int i = 0;
    while (i < length) {
      byte[] line = array[i];
      in.read(line);
      i++;
    } 
    in.close();
    L1V1Map map = null;
    try {
      map = new L1V1Map(id, tiles, xLoc, yLoc, mapData.isUnderwater, mapData.markable, mapData.teleportable, 
          mapData.escapable, mapData.isUseResurrection, mapData.isUsePainwand, mapData.isEnabledDeathPenalty, 
          mapData.isTakePets, mapData.isRecallPets, mapData.isUsableItem, mapData.isUsableSkill, 
          mapData.isGuaji, mapData.isClanPc, mapData.isPartyPc, mapData.isAlliancePc, mapData.isdropitem, mapData.isUsableShop, 
          mapData.isStart_time, mapData.isEnd_time, mapData.isweek);
    } catch (Exception e) {
      _log.error("地图资料生成数据载入异常: " + mapId, e);
    } 
    return map;
  }
  
  public Map<Integer, L1Map> read() {
    Map<Object, Object> maps = new HashMap<>();
    Map<Integer, MapData> mapDatas = MapsTable.get().getMaps();
    Iterator<Integer> iterator = mapDatas.keySet().iterator();
    while (iterator.hasNext()) {
      Integer key = iterator.next();
      MapData mapData = mapDatas.get(key);
      try {
        maps.put(key, read(key.intValue(), mapData));
      } catch (IOException e) {
        e.printStackTrace();
      } 
    } 
    return (Map)maps;
  }
}
